;*******************************************************************************
; Director - BMG
;
; Copyright (C) 2003, Nick Craig-Wood and Philip Ludlam
;
;This program is free software; you can redistribute it and/or modify it under
;the terms of the GNU General Public License as published by the Free Software
;Foundation; either version 2 of the License, or (at your option) any later
;version.
;
;This program is distributed in the hope that it will be useful, but WITHOUT ANY
;WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
;PARTICULAR PURPOSE. See the GNU General Public License for more details.
;
;You should have received a copy of the GNU General Public License along with
;this program; if not, write to the Free Software Foundation, Inc., 59 Temple
;Place - Suite 330, Boston, MA 02111-1307, USA
;
;*******************************************************************************
;----h- Director.s.BMG
; Name
;   BMG
;
; Purpose
;   Misc calls.
;------
;*******************************************************************************


		TTL	> BMG

		GET	OSLib:oslib.hdr.OS
		GET	OSLib:oslib.hdr.Wimp
		GET	OSLib:oslib.hdr.WimpReadSysInfo
		GET	OSLib:oslib.hdr.OSFind
		GET	OSLib:oslib.hdr.OSByte
		GET	OSLib:oslib.hdr.Buffer
		GET	OSLib:oslib.hdr.FileSwitch
		GET	OSLib:oslib.hdr.Hourglass
		GET	OSLib:oslib.hdr.DDEUtils
		GET	OSLib:oslib.hdr.OSModule
		GET	OSLib:oslib.hdr.OSFSControl
		GET	AsmLib2:hdr.RegsBoth
		GET	AsmLib2:hdr.MacrosBoth
		GET	h.WorkSpace
		GET	h.ListMacros
		GET	h.Constants
		GET	AsmLib2:hdr.DebugBoth
		GET	h.Memory
		GET	h.ModuleHead
		GET	h.Messages
		GET	h.Menus
		GET	h.Task
		GET	h.Filter
		GET	h.Sort

		AREA	|BMG|, CODE, READONLY


;*******************************************************************************
;Variables local to the BMG
;These are allocated from a block in the main workspace
;*******************************************************************************


			^	(:INDEX: BMGVars), wp

CurrentMenuBlock	#	4
IgnoreCommands		#	4

			ASSERT	@ <= EndBMGVars


;*******************************************************************************
;----f- Director.s.BMG.Star_Menu
; Name
;   DoMenu
;
; Purpose
;   This starts a new menu
;
; Entry
;   none
;
; Exit
;   none
;------
;*******************************************************************************


Help_Menu	FOREXPORT
	[	OSVersion = 310
		DCB	"Create a menu with an optional internal name.", 13
	|
		DCB	"Help_Menu", 0
	]

Syntax_Menu	FOREXPORT
	[	OSVersion = 310
		DCB	"Syntax: *Menu <title> [<alias>] [-key <key>] [-temp] [-remove]", 0
	|
		DCB	"Syntax_Menu", 0
	]
		ALIGN

Args_Menu	DCB	"/G,/G,key/G,temp/S,remove/S", 0
		ALIGN

Star_Menu	FOREXPORT
		LDR	wp, [r12]
DoMenu		SaveRegs
		ROUTINE_SF	NONE
scratch$l	#	0
arg_text$l	#	4
arg_alias$l	#	4
arg_key$l	#	4
arg_temp$l	#	4
arg_remove$l	#	4
space$l		#	scratch_size - :INDEX: @
		END_SF

		LDR	lr, IgnoreCommands		; check if accepting commands
		CMP	lr, #0
		BNE	NormalReturn

		MOV	r1, r0				; translate given string
		ADR	r0, Args_Menu
		ADR	r2, scratch$l
		MOV	r3, #scratch_size
		SWI	XOS_ReadArgs
		BVS	ErrorReturn

		LDR	lr, CurrentMenuBlock		; menu already open?
		CMP	lr, #0
		BLNE	End_Menu

		LDR	r0, arg_text$l
		BL	sort_out_gstrans
		LDR	r0, arg_alias$l
		BL	sort_out_gstrans
		LDR	r0, arg_key$l
		BL	sort_out_gstrans

		LDR	r8, arg_text$l			; title
		LDR	r9, arg_alias$l			; alias
		CMP	r9, #0
		MOVEQ	r9, r8				; use title as alias

kill$l		MOV	r0, r9
		ADR	r1, MenuStoredAnchor
		BL	MenuBlockFind			; r0  found, r1  previous
		BNE	exitkill$l
		BL	MenuBlockDestroy		; kill any old menus with the same name
		B	kill$l

exitkill$l	LDR	lr, arg_remove$l		; if we were removing the menu then
		TEQ	lr, #0				; end since it is now gone
		BNE	NormalReturn

		MOV	r0, r9				; name
		LDR	r2, arg_temp$l			; temporary status
		BL	MenuBlockCreate
		BVS	ErrorReturn
		MOV	r11, r0
                STR	r11, CurrentMenuBlock

		MOV	r0, r8				; title
		LDR	r1, arg_key$l			; key string
		BL	MenuInitialise			; start a menu
		BVS	ErrorReturn

		B	NormalReturn


;*******************************************************************************
;----f- Director.s.BMG.Star_EndMenu
; Name
;   Star_EndMenu
;
; Purpose
;   This finishes the current menu
;
; Entry
;   none
;
; Exit
;   none
;------
;*******************************************************************************


Help_EndMenu	FOREXPORT
	[	OSVersion = 310
		DCB	"Finish the current menu.", 13
	|
		DCB	"Help_EndMenu", 0
	]

Syntax_EndMenu	FOREXPORT
	[	OSVersion = 310
		DCB	"Syntax: *EndMenu [-sort]", 0
	|
		DCB	"Syntax_EndMenu", 0
	]
		ALIGN

Args_EndMenu	DCB	"sort/S", 0
		ALIGN

Star_EndMenu	FOREXPORT
		LDR	wp, [r12]
DoEndMenu	SaveRegs
		ROUTINE_SF	NONE
scratch$l	#	0
arg_sort$l	#	4
space$l		#	scratch_size - :INDEX: @
		END_SF

		LDR	lr, IgnoreCommands
		CMP	lr, #0
		BNE	NormalReturn

		LDR	r11, CurrentMenuBlock
		CMP	r11, #0				; are we in a menu?
		BEQ	NormalReturn

		MOVS	r1, r0				; translate given string
		BEQ	no_string$l
		ADR	r0, Args_EndMenu
		ADR	r2, scratch$l
		MOV	r3, #scratch_size
		SWI	XOS_ReadArgs
		BVS	ErrorReturn

		LDR	r0, arg_sort$l
		CMP	r0, #0
		BEQ	no_sort$l
		LDR	r11, CurrentMenuBlock		; current menu
		MOV	r0, #0				; sort from start
		MOV	r1, #&70000000			; to end
		BL	SortMenuBlock

no_sort$l
no_string$l
		BL	End_Menu

		B	NormalReturn


;*******************************************************************************
;----f- Director.s.BMG.End_Menu
; Name
;   End_Menu
;
; Purpose
;   Close/finish adding items to the current menu
;
; Entry
;   none
;
; Exit
;   none
;------
;*******************************************************************************


End_Menu	ROUTINE	"r0"

		MOV	r0, #0
		STR	r0, CurrentMenuBlock		; show we don't have a current menu
		STR	r0, CurrentMenuItem		; show we don't have a current menu item

		;;;; could tidy length of menu block and string block here

		EXIT


;*******************************************************************************
;----f- Director.s.BMG.Star_Option
; Name
;   Star_Option
;
; Purpose
;   This adds a menu option to the current menu
;
; Entry
;   none
;
; Exit
;   none
;------
;*******************************************************************************


Help_Option	FOREXPORT
	[	OSVersion = 310
		DCB	"Add an option to the current menu.", 13
		DCB	"You must supply a text or a path or both.", 13
	|
		DCB	"Help_Option", 0
	]

Syntax_Option	FOREXPORT
	[	OSVersion = 310
		DCB	"Syntax: *Option <text> | -path <file|directory> [-tick] [-bg <col>] [-fg <col>] [-sub [<menu>|*]] [-len <len> [-allow <characters>]] [-dash] [-grey] [-key <key>] [-up] [-nosprite] [-sprite <name>]", 0
	|
		DCB	"Syntax_Option", 0
	]
		ALIGN

Args_Option	DCB	"/G,path/G,tick/S,bg/E,fg/E,sub/G,len/E,allow/G,dash/S,grey/S,key/G,up/S,nosprite/S,sprite/G", 0
		ALIGN

Star_Option	FOREXPORT
		LDR	wp, [r12]
DoOption	SaveRegs
		ROUTINE_SF	NONE
scratch$l	#	0
arg_text$l	#	4
arg_path$l	#	4
arg_tick$l	#	4
arg_bg$l	#	4
arg_fg$l	#	4
arg_sub$l	#	4
arg_len$l	#	4
arg_allow$l	#	4
arg_dash$l	#	4
arg_grey$l	#	4
arg_key$l	#	4
arg_up$l	#	4
arg_nosprite$l	#	4
arg_sprite$l	#	4
space$l		#	scratch_size - :INDEX: @
		END_SF

		LDR	lr, IgnoreCommands		; check if accepting commands
		CMP	lr, #0
		BNE	NormalReturn

		LDR	lr, CurrentMenuBlock		; ignore if no current menu
		CMP	lr, #0
		BEQ	NormalReturn

		MOV	r1, r0
		ADR	r0, Args_Option
		ADR	r2, scratch$l
		MOV	r3, #scratch_size
		SWI	XOS_ReadArgs
		BVS	ErrorReturn

		LDR	r0, arg_text$l
		BL	sort_out_gstrans
		LDR	r0, arg_path$l
		BL	sort_out_gstrans
		LDR	r0, arg_sub$l
		BL	sort_out_gstrans
		LDR	r0, arg_key$l
		BL	sort_out_gstrans
		LDR	r0, arg_sprite$l
		BL	sort_out_gstrans
		LDR	r0, arg_allow$l
		BL	sort_out_gstrans

		LDR	r11, CurrentMenuBlock		; r11  MenuBlock

		LDR	r7, arg_len$l			; r7  arg_len
		LDR	r6, arg_allow$l			; r6  arg_allow
		CMP	r7, #0
		BNE	checkallow$l
		CMP	r6, #0
		BNE	NoAllowNotLen			; error if -allow is supplied with out -len
checkallow$l

		LDR	r7, arg_text$l			; r7  arg_text
		LDR	r6, arg_path$l			; r6  arg_path
		CMP	r7, #0
		CMPEQ	r6, #0
		BEQ	NoTextGiven			; check for text argument, and continue if found

		CMP	r6, #0
		BNE	path$l

		;text item

nopath$l	LDR	r0, arg_len$l
		CMP	r0, #0
		MOVEQ	r1, #0				; r1 = 0 => read length of string
		BEQ	nolen$l
		BL	read_eval
		MOV	r1, r0				; r1 = length of input
nolen$l
		MOV	r0, r7
		LDR	r2, arg_key$l			; r2  key string
		LDR	r3, arg_sprite$l		; r3  sprite
		LDR	r5, arg_allow$l			; r5  allowable characters
		BL	MenuAddTextItem
		BVS	ErrorReturn

		LDR	r8, CurrentMenuItem		;r8  menu item

		LDR	r3, arg_sub$l
		CMP	r3, #0
		BEQ	nosubmenu$l

		MOV	r0, #1
		STR	r0, [r8, #Wimp_MenuEntry_sub_menu] ; show we have a sub menu
		LDR	r0, [r8, #Wimp_MenuEntry_menu_flags]
		ORR	r0, r0, #Wimp_MenuGiveWarning
		STR	r0, [r8, #Wimp_MenuEntry_menu_flags] ; and it is auto generated

		MOV	r0, r3
		ADR	r1, UseText
		BL	strcmpi
		LDREQ	r3, arg_text$l			; if string is "*" then use the arg_text

		MOV	r0, r3
		ADD	r4, r11, #MenuBlock_strings
		BL	StringCopy			; copy the string into the block for the sub-menu
		BVS	ErrorReturn
		BL	MenuStringsRelocate

nosubmenu$l	B	options$l

		; path item

path$l		LDR	r0, arg_sub$l
		CMP	r0, #0
		BNE	NotSubAndPath
;;;;		Could Iconsprites or Filer_Boot applications here

		MOV	r0, r6				; path
		MOV	r1, r7				; text or 0 for use leaf
		LDR	r2, arg_key$l			; r2  key string
		LDR	r3, arg_up$l			; up menus?
		TEQ	r3, #0
		MOVNE	r3, #2_01			; up menus only
		LDR	lr, arg_nosprite$l
		CMP	lr, #0
		ORRNE	r3, r3, #1<<6			; show no sprite wanted
		BL	MenuAddPathItem
		BVS	ErrorReturn

		; process options

options$l	LDR	r8, CurrentMenuItem		; r8  menu item

		; tick

		LDR	lr, arg_tick$l
		CMP	lr, #0
		LDRNE	r0, [r8, #Wimp_MenuEntry_menu_flags]
		ORRNE	r1, r0, #Wimp_MenuTicked
		STRNE	r1, [r8, #Wimp_MenuEntry_menu_flags]

		; bg

		LDR	lr, arg_bg$l
		CMP	lr, #0
		LDRNEB	lr, [lr, #1]			; read actual eval-ed value
		ANDNE	lr, lr, #&F			; in range
		LDRNE	r0, [r8, #Wimp_MenuEntry_icon_flags]
		BICNE	r0, r0, #Wimp_IconBGColour
		ORRNE	r0, r0, lr, LSL#Wimp_IconBGColourShift
		STRNE	r0, [r8, #Wimp_MenuEntry_icon_flags]

		; fg

		LDR	lr, arg_fg$l
		CMP	lr, #0
		LDRNEB	lr, [lr, #1]			; read actual eval-ed value
		ANDNE	lr, lr, #&F			; in range
		LDRNE	r0, [r8, #Wimp_MenuEntry_icon_flags]
		BICNE	r0, r0, #Wimp_IconFGColour
		ORRNE	r0, r0, lr, LSL#Wimp_IconFGColourShift
		STRNE	r0, [r8, #Wimp_MenuEntry_icon_flags]

		; len

		LDR	lr, arg_len$l
		CMP	lr, #0
		LDRNE	r0, [r8, #Wimp_MenuEntry_menu_flags] ; make menu writeable
		ORRNE	r0, r0, #Wimp_MenuWritable
		STRNE	r0, [r8, #Wimp_MenuEntry_menu_flags]

		; dash

		LDR	lr, arg_dash$l
		CMP	lr, #0
		BLNE	MenuUnderlineItem

		; grey

		LDR	lr, arg_grey$l
		CMP	lr, #0
		LDRNE	r0, [r8, #Wimp_MenuEntry_icon_flags]
		ORRNE	r0, r0, #Wimp_IconShaded
		STRNE	r0, [r8, #Wimp_MenuEntry_icon_flags] ; shade the entry

		B	NormalReturn

UseText		EQUS0A	"*"
NoTextGiven	ReportErrorMT	"$NoTextOrPath", Error_NoTextOrPath
NotSubAndPath	ReportErrorMT	"$NotPathAndSub", Error_NotPathAndSub
NoAllowNotLen	ReportErrorMT	"$NoAllowWithoutLen", Error_NoAllowWithoutLen
		ALIGN


;*******************************************************************************
;----f- Director.s.BMG.Star_Dash
; Name
;   Star_Dash
;
; Purpose
;   This adds a dash to the last menu item
;
; Entry
;   none
;
; Exit
;   none
;------
;*******************************************************************************


Help_Dash	FOREXPORT
	[	OSVersion = 310
		DCB	"This adds a dash to the last option.", 13
	|
		DCB	"Help_Dash", 0
	]

Syntax_Dash	FOREXPORT
	[	OSVersion = 310
		DCB	"Syntax: *Dash", 0
	|
		DCB	"Syntax_Dash", 0
	]
		ALIGN

Star_Dash	FOREXPORT
		LDR	wp, [r12]
DoDash		SaveRegs
		ROUTINE	NONE

		LDR	lr, IgnoreCommands		; check if accepting command
		CMP	lr, #0
		BNE	NormalReturn

		LDR	r11, CurrentMenuBlock
		CMP	r11, #0				; are we in a menu?
		LDRNE	r8, CurrentMenuItem
		CMPNE	r8, #0				; is there a preceding menu option?

		BLNE	MenuUnderlineItem
		B	NormalReturn


;*******************************************************************************
;----f- Director.s.BMG.Star_Command
; Name
;   Star_Command
;
; Purpose
;   This adds a command to the last menu option declared
;
; Entry
;   none
;
; Exit
;   none
;------
;*******************************************************************************


Help_Command	FOREXPORT
	[	OSVersion = 310
		DCB	"Add a command to the previous menu option.", 13
	|
		DCB	"Help_Command", 0
	]

Syntax_Command	FOREXPORT
	[	OSVersion = 310
		DCB	"Syntax: *Command <*command>", 0
	|
		DCB	"Syntax_Command", 0
	]
		ALIGN

Star_Command	FOREXPORT
		LDR	wp, [r12]
DoCommand	SaveRegs
		ROUTINE	NONE

		LDR	lr, IgnoreCommands		; check if accepting commands
		CMP	lr, #0
		BNE	NormalReturn

		LDR	r11, CurrentMenuBlock
		CMP	r11, #0				; are we in a menu?
		LDRNE	r8, CurrentMenuItem
		CMPNE	r8, #0				; is there a preceding menu option?
		BEQ	NormalReturn

		MOV	r9, r0				; r9  command line

		LDR	r1, [r8, #Wimp_MenuEntry_icon_flags]
		AND	r0, r1, #Wimp_IconESG
		MOV	r0, r0, LSR#Wimp_IconESGShift
		CMP	r0, #MenuEntryText		; must be text or command1
		CMPNE	r0, #MenuEntryCommand1
		BNE	cantadd$l
		BIC	r1, r1, #Wimp_IconESG		; clear out field
		CMP	r0, #MenuEntryText
		ORREQ	r1, r1, #MenuEntryCommand1 << Wimp_IconESGShift ; text -> command1
		ORRNE	r1, r1, #MenuEntryCommand2 << Wimp_IconESGShift ; command1 -> command2
		STR	r1, [r8, #Wimp_MenuEntry_icon_flags]

		MOV	r0, r9
		ADD	r4, r11, #MenuBlock_strings
		BL	StringCopy			; copy the string into the block for the sub-menu
		BL	MenuStringsRelocate

		B	NormalReturn

cantadd$l	ReportErrorMT	"$CantAddCommand", Error_CantAddCommand


;*******************************************************************************
;----f- Director.s.BMG.OnOrOff
; Name
;   OnOrOff
;
; Purpose
;   This processes a string, returning 1 or 0 depending on the string
;
; Entry
;   r0  string
;
; Exit
;   If an error occured:
;     r0 = pointer to a valid error block
;     VS
;   Otherwise
;     VC
;     r0 = 0  off or 1  on
;------
;*******************************************************************************


OnOrOff		ROUTINE	"r1-r4", EXPORT

		MOV	r1, r0				; r1  string
		MOV	r4, #0				; # string
		ADR	r2, start$l
		ADR	r3, end$l

loop$l		MOV	r0, r2
		BL	strcmpi
		BEQ	done$l
		BL	strlen1
		ADD	r2, r2, r0
		CMP	r2, r3
		BLT	loop$l

		ADR	r0, dunno$l
		BL	MessageErrorLookup
		SetV
		EXIT

done$l		ADR	r3, off$l
		CMP	r2, r3
		MOVLT	r0, #0
		MOVGT	r0, #1
		ClearV
		EXIT

start$l		DCB	"0",   0
		DCB	"N",   0
		DCB	"No",  0
		DCB	"Off", 0
off$l		DCB	"1",   0
		DCB	"Y",   0
		DCB	"On",  0
		DCB	"Yes", 0
end$l
		ALIGN

dunno$l		ERROR	"$BadParameter", Error_BadParameter


;*******************************************************************************
;----f- Director.s.BMG.OnOrOffOrSmashOrToggle
; Name
;   OnOrOffOrSmashOrToggle
;
; Purpose
;   This processes a string, returning 0, 1, 2 or 3 depending on the string
;
; Entry
;   r0  string
;
; Exit
;   If an error occured:
;     r0 = pointer to a valid error block
;     VS
;   Otherwise
;     VC
;     r0 = 0  off, 1  on, 2  smash, 3  toggle
;------
;*******************************************************************************


OnOrOffOrSmashOrToggle	ROUTINE	"r1-r4"

		MOV	r1, r0				; r1  string
		MOV	r4, #0				; # string
		ADR	r2, start$l
		ADR	r3, end$l

loop$l		MOV	r0, r2
		BL	strcmpi
		BEQ	done$l
		BL	strlen1
		ADD	r2, r2, r0
		CMP	r2, r3
		BLT	loop$l

		ADR	r0, dunno$l
		BL	MessageErrorLookup
		SetV
		EXIT

done$l
		ADR	r3, on$l
		CMP	r2, r3			; Is it before on?
		MOVLT	r0, #0			; Yes it's off
		BLT	exit$l

		ADR	r3, smash$l
		CMP	r2, r3			; Is it before smash?
		MOVLT	r0, #1			; Yes it's on
		BLT	exit$l

		ADR	r3, toggle$l
		CMP	r2, r3			; Is it before toggle?
		MOVLT	r0, #2			; Yes it's smash
		MOVGE	r0, #3			; No, it's toggle


exit$l		ClearV
		EXIT

start$l
off$l		DCB	"Off",    0
		DCB	"No",     0
		DCB	"0",      0
		DCB	"N",      0
on$l		DCB	"On",     0
		DCB	"Yes",    0
		DCB	"1",      0
		DCB	"Y",      0
smash$l		DCB	"Smash",  0
		DCB	"S",      0
		DCB	"2",      0
		DCB	"X",      0
toggle$l	DCB	"Toggle", 0
		DCB	"T",      0
		DCB	"3",      0
end$l
		ALIGN

dunno$l		ERROR	"$BadParameter", Error_BadParameter


;*******************************************************************************
;----f- Director.s.BMG.Star_MenuProcessing
; Name
;   Star_MenuProcessing
;
; Purpose
;   This turns Menu processing On or Off
;
; Entry
;   none
;
; Exit
;   none
;------
;*******************************************************************************


Help_MenuProcessing	FOREXPORT
	[	OSVersion = 310
		DCB	"Turn menu processing on or off.", 13
	|
		DCB	"Help_MenuProcessing", 0
	]

Syntax_MenuProcessing	FOREXPORT
	[	OSVersion = 310
		DCB	"Syntax: *MenuProcessing <On|Off|1|0|Yes|No|Y|N|Smash|S|X|2|Toggle|T|3>", 0
	|
		DCB	"Syntax_MenuProcessing", 0
	]
		ALIGN

Args_MenuProcessing	DCB	"/G", 0
		ALIGN

Star_MenuProcessing	FOREXPORT
		LDR	wp, [r12]

DoMenuProcessing	SaveRegs
		ROUTINE_SF	NONE
scratch$l	#	0
arg_text$l	#	4
space$l		#	scratch_size - :INDEX: @
		END_SF

		MOV	r1, r0				; translate given string
		ADR	r0, Args_MenuProcessing
		ADR	r2, scratch$l
		MOV	r3, #scratch_size
		SWI	XOS_ReadArgs
		BVS	ErrorReturn

		LDR	r0, arg_text$l
		CMP	r0, #0
		BEQ	NormalReturn
		BL	sort_out_gstrans

		BL	OnOrOffOrSmashOrToggle
		BVS	ErrorReturn
		CMP	r0, #0
		BEQ	off$l
		CMP	r0, #2
		BEQ	smash$l
		CMP     r0, #3
		BEQ     toggle$l

on$l
		LDR	r0, IgnoreCommands
		SUB	r0, r0, #1
		CMP	r0, #0
		MOVMI	r0, #0
		STR	r0, IgnoreCommands
		B	exit$l

off$l
		LDR	r0, IgnoreCommands
		ADD	r0, r0, #1
		STR	r0, IgnoreCommands
		B	exit$l

smash$l
		MOV	r0, #0
		STR	r0, IgnoreCommands
		B	exit$l

toggle$l
		LDR	r0, IgnoreCommands
		EOR	r0, r0, #1
		STR	r0, IgnoreCommands
;		B	exit$l

exit$l
		ADR	r0, $Name.MenuProcessing$l
		LDR	r1, IgnoreCommands
		BL	SetVarValN
		BVS	ErrorReturn
		B	NormalReturn

$Name.MenuProcessing$l		DCB	"$Name.$MenuProcessing", 0


;*******************************************************************************
;----f- Director.s.BMG.OutputKey
; Name
;   OutputKey
;
; Purpose
;   This outputs the wimp key into the keyboard buffer
;
; Entry
;   r0 = Wimp key number
;
; Exit
;   none
;------
;*******************************************************************************


OutputKey	ROUTINE	"r0-r3"

		MOV	r3, r0
		MOV	r0, #OSByte_BufferInsert
		MOV	r1, #Buffer_Keyboard

		SWI	XOS_IntOff

		; &000 - okay
		; &080 - escape
		; &100 - shouldn't happen
		; &180 - okay

		AND	lr, r3, #&180
		TEQ	lr, #&080
		MOVEQ	r2, #0
		SWIEQ	XOS_Byte

		AND	r2, r3, #&FF
		SWI	XOS_Byte

		SWI	XOS_IntOn

		EXIT


;*******************************************************************************
;----f- Director.s.BMG.Star_ProcessKeys
; Name
;   Star_ProcessKeys
;
; Purpose
;   This sends the input string into the current input process
;
; Entry
;   ?
;
; Exit
;   none
;------
;*******************************************************************************


Help_ProcessKeys	FOREXPORT
	[	OSVersion = 310
		DCB	"Sends the parameters to the current input focus.", 13
	|
		DCB	"Help_ProcessKeys", 0
	]

Syntax_ProcessKeys	FOREXPORT
	[	OSVersion = 310
		DCB	"Syntax: *ProcessKeys [[][^]<key>|""<string>""]^", 0
	|
		DCB	"Syntax_ProcessKeys", 0
	]
		ALIGN

Star_ProcessKeys	FOREXPORT
		ModuleVeneer
		ROUTINE

		MOV	r8, r0				; r8  command line

loop$l		LDRB	r0, [r8], #1
		CMP	r0, #32
		BLT	NormalReturn
		BEQ	loop$l
		CMP	r0, #'"'
		BEQ	strout$l			; output string, skipping "

		SUB	r0, r8, #1			; r0  start of string
loop2$l		LDRB	r1, [r8], #1
		CMP	r1, #32
		BGT	loop2$l

		LDRB	r2, [r8, #-1]!			; get byte that was in string
		MOV	lr, #0
		STRB	lr, [r8]			; terminate string
		BL	LookUpKey
		BVS	ErrorReturn
		STRB	r2, [r8]			; restore byte that was in string
		BIC	r0, r0, #ShiftMod + CtrlMod + AltMod
		BL	OutputKey
		B	loop$l

strout$l	LDRB	r0, [r8], #1
		CMP	r0, #'"'
		BEQ	loop$l
		BL	OutputKey
		B	strout$l


;*******************************************************************************
;----f- Director.s.BMG.sort_out_gstrans
; Name
;   sort_out_gstrans
;
; Purpose
;   This makes a result from OS_ReadArgs with the /G option
;   into a null terminated string
;
; Entry
;   r0  string
;
; Exit
;   Z (EQ) set if it is a null string
;------
;*******************************************************************************


sort_out_gstrans	ROUTINE	"r0-r3", EXPORT

		CMP	r0, #0				; null string
		BEQ	exit$l

		MOV	r1, r0
		LDRB	r2, [r1], #1			; length lsb
		LDRB	r3, [r1], #1			; length msb
		ORRS	r3, r2, r3, LSL #8		; length
		BEQ	dont$l

loop$l		LDRB	r2, [r1], #1			; move string up, overwriting length
		STRB	r2, [r0], #1
		SUBS	r3, r3, #1
		BNE	loop$l
		ClearZ

dont$l		MOV	r2, #0				; null terminate string
		STRB	r2, [r0], #1

exit$l		EXIT


;*******************************************************************************
;----f- Director.s.BMG.read_eval
; Name
;   read_eval
;
; Purpose
;   This reads the /E value pointed to by r0
;
; Entry
;   r0  /E value
;
; Exit
;   r0 = value
;------
;*******************************************************************************


read_eval	ROUTINE	"r1", EXPORT
		LDRB	r1, [r0, #1]
		LDRB	lr, [r0, #2]
		ORR	r1, r1, lr, LSL#8
		LDRB	lr, [r0, #3]
		ORR	r1, r1, lr, LSL#16
		LDRB	lr, [r0, #4]
		ORR	r0, r1, lr, LSL#24
		EXIT


;*******************************************************************************
;----f- Director.s.BMG.GetLine
; Name
;   GetLine
;
; Purpose
;   This gets a line from the file handle given
;   It skips any leading spaces or control characters and reads characters
;   or up to the next control character
;   The string is left 0 terminated
;   Any tabs are translated into spaces
;   It will return an error if more that StringSize characters are received
;   or the FS gives an error
;
; Entry
;   r0  file handle
;   r1  string
;
; Exit
;   If an error occured:
;     r0 = pointer to valid error block
;     VS
;   Otherwise
;     VC
;     r0 = EOF
;     r1 = lines used from input
;------
;*******************************************************************************


GetLine		ROUTINE	"r2-r4"

		MOV	r3, #StringSize-1		; max characters
		MOV	r2, r1				; r2  string
		MOV	r1, r0				; r1 = file handle
		MOV	r4, #0				; lines used

		MOV	lr, #0
		STRB	lr, [r2]			; null terminate

skip$l		SWI	XOS_BGet			; skip initial line feeds, spaces or tabs
		BVS	error$l
		BCS	eof$l

		CMP	r0, #10				; line feeds
		ADDEQ	r4, r4, #1			; lines skipped
		CMPNE	r0, #32				; space
		CMPNE	r0, #9				; tab
		BLE	skip$l

store$l		SUBS	r3, r3, #1
		BLT	toolong$l
		STRB	r0, [r2], #1			; store the character in the string

		MOV	lr, #0
		STRB	lr, [r2]			; null terminate

		SWI	XOS_BGet
		BVS	error$l
		BCS	eof$l

		CMP	r0, #9
		MOVEQ	r0, #' '			; translate TAB into SPACE

		CMP	r0, #10				; store up to a line feed
		BNE	store$l
		ADD	r4, r4, #1			; lines skipped

		MOV	r0, #0				; not eof
		B	exit$l

eof$l		MOV	r0, #1				; show eof
		ADD	r4, r4, #1			; eof counts as a line feed
exit$l		MOV	r1, r4
		ClearV
		EXIT

toolong$l	ADR	r0, toolongmsg$l
		BL	MessageErrorLookup

error$l		MOV	r1, r4
		EXIT

toolongmsg$l	ERROR	"$LineTooLong", Error_LineTooLong


;*******************************************************************************
;----f- Director.s.BMG.Star_DirectorObey
; Name
;   Star_DirectorObey
;
; Purpose
;   This executes the commands held in the file pointed to by r0
;
; Entry
;   r0  command / file to DirectorObey
;
; Exit
;   none
;------
;*******************************************************************************


		MACRO
$label		IsIt	$name, $exit
$label		ADR	r0, %FT00
		BL	strcmpi
		MOV	r0, r7				; command line
		ADRF	lr, $exit
		BEQ	Do$name
		B	%FT10
00
		DCB	"$name", 0
		ALIGN
10
		MEND

Help_$Name.Obey	FOREXPORT
	[	OSVersion = 310
		DCB	"This command is equivalent to *Obey except it searches for $Name *commands with high priority. "
		DCB	"It is useful for setting up $Name quickly.", 13
	|
		DCB	"Help_DirectorObey", 0
	]

Syntax_$Name.Obey	FOREXPORT
	[	OSVersion = 310
		DCB	"Syntax: *$Name.Obey <file> [-verbose]", 0
	|
		DCB	"Syntax_DirectorObey", 0
	]

Args_$Name.Obey	DCB	"/G/A,verbose/S", 0
		ALIGN

Star_$Name.Obey	FOREXPORT
		LDR	wp, [r12]
Do$Name.Obey	SaveRegs
		ROUTINE_SF	NONE
handle$l	#	4
eof$l		#	4
line$l		#	StringSize

scratch$l	#	0
arg_file$l	#	4
arg_verbose$l	#	4
dummy$l		#	scratch_size - :INDEX: @

line_no$l	#	16
error_block$l	#	StringSize
		END_SF

		MOV	r1, r0				; translate given string
		ADR	r0, Args_$Name.Obey
		ADR	r2, scratch$l
		MOV	r3, #scratch_size
		SWI	XOS_ReadArgs
		BVS	ErrorReturn

		MOV	lr, #0
		STR	lr, handle$l			; file handle (0 for no file)
		MOV	r8, #0				; line number

		SWI	XHourglass_On

		LDR	r0, arg_file$l
		BL	sort_out_gstrans
		MOV	r1, r0
		MOV	r0, #OSFind_Openin + OSFind_ErrorIfAbsent + OSFind_ErrorIfDir
		SWI	XOS_Find
		BVS	error$l
		STR	r0, handle$l

loop$l		LDR	r0, handle$l
		ADR	r1, line$l
		BL	GetLine
		ADD	r8, r8, r1			; count up lines used
		BVS	error$l
		STR	r0, eof$l

		MOV	r0, r8, LSR#2
		SWI	XHourglass_Percentage		; visual indication of line number

		LDR	lr, arg_verbose$l
		CMP	lr, #0
		BEQ	not_verbose$l
		WriteS	"> "
		ADR	r0, line$l
		SWI	XOS_Write0
		SWI	XOS_NewLine
not_verbose$l

		ADR	r7, line$l
space$l		LDRB	r1, [r7], #1			; find first space or control
		CMP	r1, #32
		BGT	space$l
		SUB	r7, r7, #1

		MOV	r6, r7				; r6  terminator
		LDRB	r5, [r6]			; r5 = character overwritten
		MOV	lr, #0
		STRB	lr, [r7]			; terminate the first part

skip$l		CMP	r1, #32
		LDREQB	r1, [r7, #1]!			; r7  first non space
		BEQ	skip$l

		CMP	r1, #"|"			; ignore comments
		BEQ	next$l

		ADR	r1, line$l

		IsIt	Option,		cmddone$l
		IsIt	Command,	cmddone$l
		IsIt	Dash,		cmddone$l
		IsIt	Menu,		cmddone$l
		IsIt	EndMenu,	cmddone$l
		IsIt	MenuProcessing,	cmddone$l

		STRB	r5, [r6]			; restore character overwritten
		ADR	r0, line$l			; run the command as normal
		SWI	XOS_CLI
cmddone$l	BVS	error$l
next$l		LDR	r0, eof$l
		CMP	r0, #0
		BEQ	loop$l				; loop until eof
		MOV	r9, #0				; r9 = 0 => no error
		B	close$l

error$l		MOV	r9, r0				; r9 is error
close$l		MOV	r0, #OSFind_Close
		LDR	r1, handle$l
		CMP	r1, #0
		SWINE	XOS_Find			; close file if it was opened

		SWI	XHourglass_Off

		CMP	r9, #0
		BEQ	NormalReturn			; return if no error

	BL	StartTask
	MOV	r10, r0					; r10 = task handle

		SWI	XDDEUtils_ThrowbackStart
		BVS	error2$l

		MOV	r0, #1				; reason
		LDR	r2, arg_file$l			; file
		MOV	r3, r8				; line number
		MOV	r4, #1				; severity
		ADD	r5, r9, #4			; string
		SWI	XDDEUtils_ThrowbackSend
		BVS	error2$l

		SWI	XDDEUtils_ThrowbackEnd
;		BVS	error2$l

error2$l
	MOV	r0, r10
	BL	StopTask

		MOV	r0, r8				; line number
		ADR	r1, line_no$l
		MOV	r2, #16
		SWI	XOS_ConvertCardinal4

		ADR	r0, error_token$l
		ADR	r2, error_block$l
		MOV	r3, #StringSize
		ADD	r4, r9, #4			; point to error string
		ADR	r5, line_no$l
		LDR	r6, arg_file$l
		BL	MessageErrorLookup3
		LDR	r1, [r9]			; error number
		STR	r1, error_block$l		; store in block
		B	ErrorReturn			; throw up the error

error_token$l	DCD	0
		DCB	"Error_DirectorObey", 0
		ALIGN


;*******************************************************************************
;----f- Director.s.BMG.Star_DirectorDo
; Name
;   Star_DirectorDo
;
; Purpose
;   This GSTranses the command pointed to and runs it
;
; Entry
;   r0  command
;
; Exit
;   none
;------
;*******************************************************************************


Help_$Name.Do	FOREXPORT
	[	OSVersion = 310
		DCB	"This GSTrans the command line and then runs it.", 13
	|
		DCB	"Help_DirectorDo", 0
	]

Syntax_$Name.Do	FOREXPORT
	[	OSVersion = 310
		DCB	"Syntax: *$Name.Do <command>", 0
	|
		DCB	"Syntax_DirectorDo", 0
	]
		ALIGN

Star_$Name.Do	FOREXPORT
		LDR	wp, [r12]
Do$Name.Do	SaveRegs
		ROUTINE_SF	NONE
scratch$l	#	scratch_size
		END_SF

		ADR	r1, scratch$l
		MOV	r2, #scratch_size
		SWI	XOS_GSTrans
		BVS	ErrorReturn
		BCS	toosmall$l

		ADR	r0, scratch$l
		SWI	XOS_CLI
		BVS	ErrorReturn

		B	NormalReturn

toosmall$l	ReportErrorMT	"$BufferTooSmall", Error_BufferTooSmall


;*******************************************************************************
;----f- Director.s.BMG.StartTask
; Name
;   StartTask
;
; Purpose
;   This starts up a task if we are not running as a task already
;
; Entry
;   r0 = Task handle or 0 for not started
;
; Exit
;   none
;------
;*******************************************************************************


StartTask	ROUTINE	"r1-r3", EXPORT

		MOV	r0, #WimpReadSysInfo_Task
		SWI	XWimp_ReadSysInfo		; discover the current task handle
		BVS	start$l
		TEQ	r0, #0				; is there a current task?
		BNE	dont_start$l			; yes so don't start one

start$l		MOV	r0, #Wimp_VersionRO2		; start up a task
		LDR	r1, Task
		ADR	r2, Task
		SWI	XWimp_Initialise
		BVS	ErrorReturn
		MOV	r0, r1				; task handle
		EXIT

dont_start$l	MOV	r0, #0				; no task
		EXIT

Task		EQUS0A	"TASK"


;*******************************************************************************
;----f- Director.s.BMG.StopTask
; Name
;   StopTask
;
; Purpose
;   This stops a task started by StartTask command
;
; Entry
;   r0 = Task handle or 0 for not started
;
; Exit
;   none
;------
;*******************************************************************************


StopTask	ROUTINE	"r1-r3", EXPORT

		CMP	r0, #0
		BEQ	exit$l

		ADR	r1, Task
		SWI	XWimp_CloseDown
		BVS	ErrorReturn

exit$l		EXIT


;*******************************************************************************
;----f- Director.s.BMG.Star_DirectorParsePath
; Name
;   Star_DirectorParsePath
;
; Purpose
;   This Parses the path supplied
;
; Entry
;   r0  command
;
; Exit
;   none
;------
;*******************************************************************************


Help_$Name.ParsePath	FOREXPORT
	[	OSVersion = 310
		DCB	"This parses the path supplied into 3 system variables "
		DCB	"$Name.$$CurrentPath Leaf and Dir.", 13
	|
		DCB	"Help_DirectorParsePath", 0
	]

Syntax_$Name.ParsePath	FOREXPORT
	[	OSVersion = 310
		DCB	"Syntax: *$Name.ParsePath <path>", 0
	|
		DCB	"Syntax_DirectorParsePath", 0
	]
		ALIGN

Star_$Name.ParsePath	FOREXPORT
		LDR	wp, [r12]
Do_$Name.ParsePath	SaveRegs

		BL	SetCurrentPath

		BVS	ErrorReturn
		B	NormalReturn


;*******************************************************************************
;----f- Director.s.BMG.Star_DirectorMouseDir
; Name
;   DoDirectorMouseDir
;
; Purpose
;   This returns the path of the window the mouse pointer is over
;
; Entry
;   r0  command
;
; Exit
;   none
;------
;*******************************************************************************


Help_$Name.MouseDir	FOREXPORT
	[	OSVersion = 310
		DCB	"This sets the supplied system variable to the path of the window the pointer is over.", 13
	|
		DCB	"Help_DirectorMouseDir", 0
	]

Syntax_$Name.MouseDir	FOREXPORT
	[	OSVersion = 310
		DCB	"Syntax: *$Name.MouseDir <var_name> [-file]", 0
	|
		DCB	"Syntax_DirectorMouseDir", 0
	]
		ALIGN

Args_$Name.MouseDir	DCB	"/G,file/S", 0
		ALIGN

Star_$Name.MouseDir	FOREXPORT
		LDR	wp, [r12]
Do$Name.MouseDir	SaveRegs
		ROUTINE_SF	NONE
scratch$l	#	0
arg_var$l	#	4
arg_file$l	#	4
space$l		#	scratch_size - :INDEX: @
		;
path$l		#	StringSize
scratch2$l	#	StringSize
		END_SF


		MOV	r1, r0
		ADR	r0, Args_$Name.MouseDir
		ADR	r2, scratch$l
		MOV	r3, #scratch_size
		SWI	XOS_ReadArgs
		BVS	ErrorReturn

		LDR	r0, arg_var$l
		BL	sort_out_gstrans

	BL	StartTask
	MOV	r9, r0					; r9 = task handle

		ADR	r1, scratch2$l
		SWI	XWimp_GetPointerInfo
		BVS	ErrorReturn
		LDR	r0, scratch2$l + Wimp_Pointer_w	; r0 = window handle
		ADR	r1, path$l
		ADR	r2, scratch2$l
		BL	FindPath
		BEQ	none$l

		LDR	r0, arg_file$l
		CMP	r0, #0
		BNE	file_is_ok$l
		ADR	r0, path$l
		BL	IfFileMakeUp			; get a directory from the path
		BVS	none$l
file_is_ok$l

set$l		LDR	r0, arg_var$l			; r0  name
		ADR	r1, path$l			; r1  value
		MOV	r4, #OS_VartypeLiteralString
		BL	SetVarVal			; set the system variable
		BVS	ErrorReturn

	MOV	r0, r9
	BL	StopTask

		B	NormalReturn

none$l		MOV	r0, #0				; EQ => bad path
		STRB	r0, path$l			; make a null path string
		B	set$l


;*******************************************************************************
;----f- Director.s.BMG.Star_DirectorShowMenu
; Name
;   Star_DirectorShowMenu
;
; Purpose
;   This opens a director menu.
;   (In particular it sends a message to Director to open a menu).
;
; Entry
;   r0  command
;
; Exit
;   none
;------
;*******************************************************************************


Help_$Name.ShowMenu	FOREXPORT
	[	OSVersion = 310
		DCB	"This opens a menu.", 13
	|
		DCB	"Help_DirectorShowMenu", 0
	]

Syntax_$Name.ShowMenu	FOREXPORT
	[	OSVersion = 310
		DCB	"Syntax: *$Name.ShowMenu <menu_name>", 0
	|
		DCB	"Syntax_DirectorShowMenu", 0
	]

Args_$Name.ShowMenu	DCB	"/G", 0
		ALIGN

Star_$Name.ShowMenu	FOREXPORT
		LDR	wp, [r12]
Do$Name.ShowMenu	SaveRegs
		ROUTINE_SF	NONE
scratch$l	#	0
arg_menu$l	#	4
space$l		#	scratch_size - :INDEX: @
		;
mouseblock$l	#	Wimp_Pointer
		END_SF

		MOV	r1, r0
		ADR	r0, Args_$Name.ShowMenu
		ADR	r2, scratch$l
		MOV	r3, #scratch_size
		SWI	XOS_ReadArgs
		BVS	ErrorReturn

		LDR	r0, arg_menu$l
		BL	sort_out_gstrans
		MOV	r8, r0				; r8  menu

	BL	StartTask
	MOV	r9, r0					; r9 = task handle

		ADR	r1, mouseblock$l
		SWI	XWimp_GetPointerInfo		; where to open the menu
		BVS	ErrorReturn

		ADR	r0, mouseblock$l
		MOV	r1, r8
		MOV	r2, #0
		BL	SendOpenMenu			; send a message to open the menu
		BVS	ErrorReturn

	MOV	r0, r9
	BL	StopTask

		B	NormalReturn


;*******************************************************************************
;----f- Director.s.BMG.CanonicaliseS
; Name
;   CanonicaliseS
;
; Purpose
;   Canonicalises the supplied filename (OS_FSControl 37).
;   The canonicalised filename is put into 'TempSpace'
;
; Entry
;    r0  ptr to filename to canonicalise
;
; Exit
;   If an error occured:
;     r0 = pointer to valid error block
;     r1 = corrupted
;     VS
;   Otherwise
;     VC
;     r0  ptr to canonicalised filename
;     r1 = space required for canonicliased filename (inc. terminator)
;------
;*******************************************************************************


Canonicalise	ROUTINE "r2-r5", EXPORT

		MOV	r1, r0				; r1  filename
		MOV	r0, #OSFSControl_CanonicalisePath ; = 37
		ADR	r2, TempSpace			; output buffer
		MOV	r3, #0
		MOV	r4, #0
		MOV	r5, #StringSize
		SWI	XOS_FSControl

		MOVVC	r0, r2				; r0  canoned filename
		SUBVC	r1, r5, #StringSize		; r1 = -ve space required
		SUBVC	r1, r1, r1, LSL #1		; r1 = space required
		ADDVC	r1, r1, #1

exit$l		EXIT


;*******************************************************************************
;----f- Director.s.BMG.Star_DirectorOptions
; Name
;   Star_DirectorOptions
;
; Purpose
;
;
; Entry
;   r0  command
;
; Exit
;   none
;------
;*******************************************************************************


Help_$Name.Options	FOREXPORT
	[	OSVersion = 310
		DCB	"Set Director's internal configuration.", 13
	|
		DCB	"Help_DirectorOptions", 0
	]

Syntax_$Name.Options	FOREXPORT
	[	OSVersion = 310
		DCB	"Syntax: *$Name.Options [-memorisemenumenu (Y/N)] [-minwimpslot <size>[K]] [-maxwimpslot <size>[K]]", 13, 10

; [-canonicalisefilenames (Y/N)] [-filerbootapps (Y/N)]", 13, 10
;		DCB	 "[-movemouse (Y/N)]
;		DCB	"[-maxwimpslot <size>[K]] [-withpling (Y/N)]", 13, 10
		DCB	"  N.B. Instead of Y or N , the following can also be used: On, Off, 1, 0, Yes, No>"
		DCB	0
	|
		DCB	"Syntax_DirectorOptions", 0
	]
		ALIGN

Args_$Name.Options
		DCB	"minwimpslot/G,"
		DCB	"maxwimpslot/G,"
		DCB	"filerbootapps/G,"
		DCB	"canonicalisefilenames/G,"
		DCB	"memorisemenumenu/G,"
		DCB	"movemouse/G,"
		DCB	"withpling/G", 0
		ALIGN

Star_$Name.Options	FOREXPORT
		LDR	wp, [r12]
Do$Name.Options	SaveRegs

			ROUTINE_SF	NONE
scratch$l		#	0
arg_wimpslotmin$l	#	4
arg_wimpslotmax$l	#	4
arg_filerbootapps$l	#	4
arg_canonfilenames$l	#	4
arg_memorisemenumenu$l	#	4
arg_movemouse$l		#	4
arg_withpling$l		#	4
space$l			#	scratch_size - :INDEX: @
			END_SF

		MOV	r1, r0
		ADR	r0, Args_$Name.Options
		ADR	r2, scratch$l
		MOV	r3, #scratch_size
		SWI	XOS_ReadArgs
		BVS	ErrorReturn

		LDR	r0, arg_wimpslotmin$l
		BL	sort_out_gstrans
		LDR	r0, arg_wimpslotmax$l
		BL	sort_out_gstrans
		LDR	r0, arg_filerbootapps$l
		BL	sort_out_gstrans
		LDR	r0, arg_canonfilenames$l
		BL	sort_out_gstrans
		LDR	r0, arg_memorisemenumenu$l
		BL	sort_out_gstrans
		LDR	r0, arg_movemouse$l
		BL	sort_out_gstrans
		LDR	r0, arg_withpling$l
		BL	sort_out_gstrans

		LDR	r1, arg_wimpslotmin$l
		CMP	r1, #0
		BEQ	skip_wimpslotmin$l		; no value supplied so skip

		MOV	R0, #10				; base 10
;		LDR	r1, arg_wimpslot$l
		SWI	XOS_ReadUnsigned		; r1 = terminating character, r2 = value
		BVS	ErrorReturn

		LDRB	r0, [r1]			; load the terminating char.
		CMP	r0, #"m"			; is it "m" ?
		CMPNE	r0, #"M"			; or "M" ?
		MOVEQ	r2, r2, LSL #10			; yes
		CMPNE	r0, #"k"			; is it "k" ?
		CMPNE	r0, #"K"			; or "K" ?
		MOVEQ	r2, r2, LSL #10			; (is it M/m still?) yes
		STR	r2, OptionWimpslotMin		; Save value

skip_wimpslotmin$l

		LDR	r1, arg_wimpslotmax$l
		CMP	r1, #0
		BEQ	skip_wimpslotmax$l		; no value supplied so skip

		MOV	R0, #10				; base 10
;		LDR	r1, arg_wimpslot$l
		SWI	XOS_ReadUnsigned		; r1 = terminating character, r2 = value
		BVS	ErrorReturn

		LDRB	r0, [r1]			; load the terminating char.
		CMP	r0, #"m"			; is it "m" ?
		CMPNE	r0, #"M"			; or "M" ?
		MOVEQ	r2, r2, LSL #10			; yes
		CMPNE	r0, #"k"			; is it "k" ?
		CMPNE	r0, #"K"			; or "K" ?
		MOVEQ	r2, r2, LSL #10			; (is it M/m still?) yes
		STR	r2, OptionWimpslotMax		; Save value

skip_wimpslotmax$l

		LDR	r0, arg_memorisemenumenu$l
		CMP	r0, #0
		BEQ	skip_memorisemenumenu$l		; no value supplied so skip

;		LDR	r0, arg_memorisemenumenu$l
		BL	OnOrOff
		BVS	ErrorReturn
		STR	r0, OptionMemoriseMenuMenu

skip_memorisemenumenu$l

		B	NormalReturn


;*******************************************************************************
;----f- Director.s.BMG.StartWimpTask
; Name
;   StartWimpTask
;
; Purpose
;   Start a new WIMP task
;   It ensures that there is enough memory in the next slot for it
;
; Entry
;   r0  command to run
;
; Exit
;   If an error occured:
;     r0 = pointer to valid error block
;     VS
;   Otherwise
;     VC
;     r0  task child handle or 0 if it has exited
;------
;*******************************************************************************


StartWimpTask	ROUTINE_SF "r0-r5", EXPORT
nextslot$l	#	4
		END_SF

;		MOV	r5, r0				; r5  command

		MOV	r0, #-1
		MOV	r1, #-1
		SWI	XWimp_SlotSize
		STR	r1, nextslot$l

		LDR	lr, OptionWimpslotMin
		CMP	r1, lr
		MOVLT	r1, lr

		LDR	lr, OptionWimpslotMax
		CMP	lr, #0
		BEQ	nomax$l
		CMP	r1, lr
		MOVGT	r1, lr

nomax$l
		MOV	r0, #-1
		SWI	XWimp_SlotSize			; set next slot
		MOV	r0, r5

		LDRSP	r0, r0				; pull command
		SWI	XWimp_StartTask			; run command
		STRSP	r0, r0				; push task handle
		MOV	r5, pc				; 26-bit: get flags
		MRS	r5, CPSR			; 32-bit: get flags

		MOV	r0, #-1
		LDR	r1, nextslot$l
		SWI	XWimp_SlotSize			; reset next slot
		ClearV

		TST	r5, #V_bit			; if Wimp_StartTask errored ...
		EXIT	EQ

		SetV					; ... then set V
		EXIT


;*******************************************************************************

		END
